use serde::{Deserialize, Serialize};
use strum_macros::EnumString;

#[derive(Debug, Serialize, Deserialize)]
pub struct Pagination {
    pub page: u64,
    pub page_size: u64,
}

#[derive(Debug, EnumString, Serialize, Deserialize)]
#[strum(serialize_all = "lowercase")]
pub enum FilterFunc {
    IN,
    EQ,
    NE,
    GTE,
    GT,
    LIKE,
    LTE,
    LT,
    NULL,
    NotNull,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum FilterValue {
    String(String),
    Bool(bool),
    Int(i32),
    Number(f64),
    List(Vec<String>),
    Array(Vec<f64>),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct FilterItem {
    pub field: String,
    pub func: FilterFunc,
    pub value: Option<FilterValue>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OrderBy {
    pub field: String,
    pub desc: bool,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ListQuery {
    pub pagination: Pagination,
    pub filters: Option<Vec<FilterItem>>,
    pub search: Option<String>,
    pub order_by: Option<Vec<OrderBy>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ListResult<T> {
    pub result: Vec<T>,
    pub total: u64,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OneResultId {
    pub id: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ManyResultId {
    pub ids: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OneEffect<T> {
    pub effect: T,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ManyEffect<T> {
    pub effects: Vec<T>,
}